package com.baizhi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baizhi.dto.LoginFormDTO;
import com.baizhi.dto.Result;
import com.baizhi.dto.UserDTO;
import com.baizhi.utils.PasswordEncoder;
import com.baizhi.utils.RedisConstants;
import com.baizhi.utils.RegexUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baizhi.entity.User;
import com.baizhi.mapper.UserMapper;
import com.baizhi.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.time.Duration;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author gange
 * @since 2023-04-06
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    //获取RedisTemplate工具
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    //userMapper
    private UserMapper userMapper;

    @Override
    public Result sendCode(String phone, String sessionId) {
        // 1.校验手机号
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合，返回错误信息
            return Result.fail("手机号格式错误！");
        }
        // 3.符合，生成验证码
        String code = RandomUtil.randomNumbers(6);
        //获取操作特定数据类型的operations对象
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(RedisConstants.LOGIN_CODE_KEY+sessionId,code, Duration.ofSeconds(180));//添加有时效的数据
        // 5.发送验证码
        log.debug("发送短信验证码成功，验证码：{}", code);
        // 返回ok
        return Result.ok();
    }

    @Override
    public Result login(LoginFormDTO loginForm, String sessionId) {
        //获取 redis链接
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        // 1.校验手机号
        String phone = loginForm.getPhone();
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合，返回错误信息
            return Result.fail("手机号格式错误！");
        }
        //判断用户是否为账户密码登录
        String code = loginForm.getCode();
        if( StringUtils.isEmpty(code)){
            QueryWrapper<User> eq = new QueryWrapper<User>().eq("phone",phone);
            User user = userMapper.selectOne(eq);
            //5.判断用户是否存在
            if(ObjectUtils.isEmpty(user)){
                return Result.fail("手机号不存在");
            }
            Boolean matches = PasswordEncoder.matches(user.getPassword(), loginForm.getPassword());
            if (!matches){
                return Result.fail("密码错误");
            }
            valueOperations.set(RedisConstants.LOGIN_USER_KEY+sessionId,user);
            return Result.ok();
        }
        //不是账户密码登录则判断验证码是否正确
        String cacheCode = (String)valueOperations.get(RedisConstants.LOGIN_CODE_KEY+sessionId);
        if(StringUtils.isEmpty(cacheCode)  || !cacheCode.toString().equals(code)){
            //3.不一致，报错
            return Result.fail("验证码错误");
        }
        //一致，根据手机号查询用户
        QueryWrapper<User> eq = new QueryWrapper<User>().eq("phone",phone);
        User userDb = userMapper.selectOne(eq);
        //5.判断用户是否存在
        if(ObjectUtils.isEmpty(userDb)){
            //不存在，则创建
            User user = new User();
            user.setPhone(phone);
            user.setNickName(phone);
            userMapper.insert(user);
        }
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(userDb,userDTO);
        valueOperations.set(RedisConstants.LOGIN_USER_KEY+sessionId,userDTO);
        return Result.ok();
    }

    @Override
    public Result logout(String authorization) {
        String key = RedisConstants.LOGIN_USER_KEY+authorization;
        redisTemplate.delete(key);
        return Result.ok();
    }

}
